package clang;

import fixedpoint.RuntimeInterval;

/**
 * C-lang datatype
 */
public enum Datatype {

    UNSIGNED_SHORT {

        @Override
        public int size() {
            return 16;
        }

        @Override
        public String toString() {
            return "unsigned short";
        }

        public boolean signed() {
            return false;
        }

        @Override
        public long getLow() {
            return 0;
        }

        @Override
        public long getHigh() {
            return 65535;
        }
    },
    SIGNED_SHORT {

        @Override
        public int size() {
            return 15;
        }

        @Override
        public String toString() {
            return "signed short";
        }

        public boolean signed() {
            return true;
        }

        @Override
        public long getLow() {
            return -32768;
        }

        @Override
        public long getHigh() {
            return 32767;
        }
    },
    UNSIGNED_LONG {

        @Override
        public int size() {
            return 32;
        }

        @Override
        public String toString() {
            return "unsigned long";
        }

        public boolean signed() {
            return false;
        }

        @Override
        public long getLow() {
            return 0;
        }

        @Override
        public long getHigh() {
            return 4294967295L;
        }
    },
    SIGNED_LONG {

        @Override
        public int size() {
            return 31;
        }

        @Override
        public String toString() {
            return "signed long";
        }

        public boolean signed() {
            return true;
        }

        @Override
        public long getLow() {
            return -2147483648L;
        }

        @Override
        public long getHigh() {
            return 2147483647L;
        }
    };
    
    public abstract int size(); // number of occupied bits, not considering the sign

    @Override
    public abstract String toString();

    public abstract long getLow();

    public abstract long getHigh();

    public boolean supports(RuntimeInterval runtimeInterval) {
        return ((runtimeInterval.getLow() >= getLow()) && (runtimeInterval.getHigh() <= getHigh()));
    }

    public boolean supports(long low, long high) {
        return ((low >= getLow()) && (high <= getHigh()));
    }
}
